/*实现抽象*/
#pragma once
#include"1.detail.hpp"
#include"2.fields.hpp"
#include"3.abstract.hpp"
namespace rpcType
{
    typedef std::pair<std::string,int> Address;
    class JsonMessage : public BaseMessage//消息实现
    {
        public:
        using ptr = std::shared_ptr<JsonMessage>;
        virtual std::string serialize()override
        {
            std::string body;
            bool ret = RpcMacro::JSON::serialize(_body,body);
            if(ret ==false)
            {
                return std::string();
            }
            return body;
        }
        virtual bool unserialize(const std::string &msg)override
        {
            return RpcMacro::JSON::unserialize(msg,_body);
        }
        protected:
        Json::Value _body;
    };
    //消息请求
    class JsonRequest :public JsonMessage
    {
        public:
        using ptr = std::shared_ptr<JsonRequest>;
    };
    //消息响应
    class JsonResponse:public JsonMessage
    {
        public:
        using ptr = std::shared_ptr<JsonResponse>;
        virtual bool check()//检查
        {
            //响应中大部分的响应只有响应状态码
            //判断响应状态码字段是否存在类型是否正确
            if(_body[KEY_RCODE].isNull()==true)
            {
                ELOG("响应中没有响应状态码");
                return false;
            }
            if(_body[KEY_RCODE].isIntegral()==false)
            {
                  ELOG("响应状态码类型错误");
                  return false;
            }
            return true;
        }
        virtual RCode code()
        {
            return (RCode)_body[KEY_RCODE].asInt();//状态码转换为整型
        }
        virtual void setRCode(RCode recode)//设置响应状态码
        {
            _body[KEY_RCODE] = (int)recode;
        }
    };

    //rpc请求
    class RpcRequest :public JsonRequest
    {
        public:
        using ptr = std::shared_ptr<RpcRequest>;
        virtual bool check()override
        {
            //rpc请求中包含请求方法名称字符串，参数字段，对象
            if(_body[KEY_METHOD].isNull()==true||
               _body[KEY_METHOD].isString()==false)
               {
                ELOG("rpc请求中没有方法名称或方法名称类型错误");
                return false;
               }
               ////参数字段
            if(_body[KEY_PARAMS].isNull()==true||
                _body[KEY_PARAMS].isObject()==false)
                {
                    ELOG("RPC请求中没有参数信息或参数信息类型错误");
                    return false;
                }
                return true;
        }
        std::string method()//方法Add
        {
            return _body[KEY_METHOD].asString();
        }
        //设置方法
        void setMethod(const std::string &method_name)
        {
            _body[KEY_METHOD] = method_name;
        }
        //参数
        Json::Value params()
        {
            return _body[KEY_PARAMS];
        }
        //设置参数
        void setParams(const Json::Value &params)
        {
            _body[KEY_PARAMS] = params;
        }
    };

    //主题请求
    class TopicRequest :public JsonRequest
    {
        public:
        using ptr = std::shared_ptr<TopicRequest>;
        //主题请求中 包含请求方法名称，字符串，参数字段，对象
        virtual bool check()override
        {
            if(_body[KEY_TOPIC_KEY].isNull()==true||
                _body[KEY_TOPIC_KEY].isString()==false)
                {
                    ELOG("主题请求中没有主题名称或主题名称类型错误");
                    return false;
                }
                //参数
            if(_body[KEY_OPTYPE].isNull()==true||
                _body[KEY_OPTYPE].isString()==false)
                {
                    ELOG("主题请求中没有操作类型或操作类型的类型错误");
                    return false;
                }
            //主题操作类型中的发布
            if(_body[KEY_OPTYPE].isInt()==(int)TopicOptype::TOPIC_PUBLISH&&
                (_body[KEY_TOPIC_MSG].isNull()==true||
                _body[KEY_TOPIC_MSG].isString()==false))
                {
                    ELOG("主题请求中发布中没有消息内容字段或消息内容类型错误");
                    return false;
                }
            return true;
        }
        std::string topickey()
        {
            return _body[KEY_TOPIC_KEY].asString();
        }
        //设置主题
        void setTopicKey(const std::string &key)
        {
            _body[KEY_TOPIC_KEY] = key;
        }
        //操作类型
        TopicOptype optype()
        {
            return (TopicOptype)_body[KEY_OPTYPE].asInt();
        }
        //设置类型
        void setOptype(TopicOptype optype)
        {
            _body[KEY_OPTYPE] = (int)optype;
        }
        std::string topicmsg()//主题消息
        {
            return _body[KEY_TOPIC_MSG].asString();
        }
        //设置主题消息
        void setTopicMsg(const std::string &msg)
        {
            _body[KEY_TOPIC_MSG] = msg;
        }
    };

    //服务请求
    class ServiceRequest : public JsonRequest
    {
        public:
        using ptr = std::shared_ptr<ServiceRequest>;
        //检查
        virtual bool check()override
        {
            //请求中，方法名称-字符串，参数字段，对象
            if(_body[KEY_METHOD].isNull()==true||
                _body[KEY_METHOD].isString()==false)
                {
                    ELOG("服务请求中没有方法名称或方法名称类型错误");
                    return false;
                }
            if(_body[KEY_OPTYPE].isNull()==true||
                _body[KEY_OPTYPE].isIntegral()==false)
                {
                    ELOG("服务请求中没有操作类型或操作类型的类型错误");
                    return false;
                }
            //服务发现
            if(_body[KEY_OPTYPE].asInt()==(int)(ServiceOptype::SERVICE_DISCOVERY)&&
                (_body[KEY_HOST].isNull()==true||
                 _body[KEY_HOST].isObject()==false||
                 _body[KEY_HOST][KEY_HOST_IP].isNull()==true||
                 _body[KEY_HOST][KEY_HOST_IP].isString()==false||
                 _body[KEY_HOST][KEY_HOST_PORT].isNull()==true||
                 _body[KEY_HOST][KEY_HOST_IP].isIntegral()==false))
                 {
                    ELOG("服务请求中主机地址信息错误");
                    return false;
                }
                return true;
        }
        std::string method()//方法
        {
            return _body[KEY_METHOD].asString();
        }
        //设置方法
        void setMethod(const std::string *name)
        {
            _body[KEY_METHOD] = name;
        }
        ServiceOptype optype()
        {
            return (ServiceOptype)_body[KEY_OPTYPE].asInt();
        }
        //设置主题类型
        void setMethod(ServiceOptype optype)
        {
            _body[KEY_OPTYPE] = (int)optype;
        }
        //主机ip主机端口
        Address host()
        {
            Address addr;
            addr.first = _body[KEY_HOST][KEY_HOST_IP].asString();
            addr.second = _body[KEY_HOST][KEY_HOST_PORT].asInt();
            return addr;
        }
        //设置主机信息
        void setHost(const Address &host)
        {
            Json::Value val;
            val[KEY_HOST_IP] = host.first;
            val[KEY_HOST_PORT] = host.second;
            _body[KEY_HOST] = val;
        }
    }; 
    //rpc响应
    class Rpcresponse:public JsonResponse
    {
        public:
        using ptr = std::shared_ptr<Rpcresponse>;
        virtual bool check()override
        {
            if(_body[KEY_RCODE].isNull()==true)
            {
                ELOG("响应中没有响应状态码或状态码类型错误");
                return false;
            }
            if(_body[KEY_RESULT].isNull()==true)
            {
                ELOG("响应中没有rpc调用结果或结果类型错误");
                return false;
            }
            return true;
        }
        Json::Value result()
        {
            return _body[KEY_RESULT];
        }
        void setResult(const Json::Value &result)
        {
            _body[KEY_RESULT] = result;
        }
    };
    class TopicResponse : public JsonResponse
    {
        public:
         using ptr = std::shared_ptr<TopicResponse>;
    };
    class ServiceResponse : public JsonResponse
    {
        public:
        using ptr = std::shared_ptr<ServiceResponse>;
        virtual bool check()override
        {
            if(_body[KEY_RCODE].isNull()==true||
                _body[KEY_RCODE].isIntegral()==false)
                {
                    ELOG("响应中没有")
                }
        }
    };
    //实现消息对象的生产工厂
    class MessageFactory
    {
        public:
        static BaseMessage::ptr create(MType mtype)
        {
            switch (mtype)
            {
                //rpc请求&响应
                case MType::REQ_RPC:
                return std::make_shared<RpcRequest>();
                case MType::RSP_RPC:
                return  std::make_shared<Rpcresponse>();
                case MType::REQ_TOPIC:
                return std::make_shared<TopicRequest>();
                case MType::RSP_TOPIC:
                return std::make_shared<TopicResponse>();
                case MType::REQ_SERVICE:
                return std::make_shared<ServiceRequest>();
                case MType::RSP_SERVICE:
                return std::make_shared<ServiceResponse>();
            }
            return BaseMessage::ptr();
        }
        template<typename T,typename ...Args>
        static std::shared_ptr<T> cerate(Args&& ...args)
        {
            return std::make_shared<T>(std::forward(ages)...);
        }
    };
}